<template>
  <div class="online-work-flow-form" style="position: relative; height: 100%;">
    <van-form ref="form"
      :label-width="(form.labelWidth || 100) + 'px'"
      label-align="left"
    >
      <online-custom-block v-if="isReady" :widgetList="form.widgetList" />
    </van-form>
    <!-- 弹出子表单 -->
    <van-popup
      v-if="showSubPage"
      v-model="showSubPage"
      position="right"
      :overlay="false"
      get-container="body"
      style="height: 100vh; width: 100vw; background: #F6F6F6;"
    >
      <online-form :formId="subFormId" :rowData="editRowData" @close="onCloseSubForm" :saveData="false"  />
    </van-popup>
  </div>
</template>

<script>
import { OnlineFormMixins } from './onlineFormMixins.js';
import { FlowOperationController } from '@/api/flowController.js';

export default {
  name: 'onlineWorkFlowForm',
  props: {
    formConfig: {
      type: Object,
      required: true
    },
    flowInfo: {
      type: Object
    },
    readOnly: {
      type: Boolean,
      default: false
    }
  },
  mixins: [OnlineFormMixins],
  provide () {
    return {
      form: () => {
        return {
          ...this.form,
          readOnly: this.readOnly || this.taskReadOnly,
          getDictDataList: this.getDictDataList,
          getWidgetValue: this.getWidgetValue,
          getWidgetVisible: this.getWidgetVisible,
          onValueChange: this.onValueChange,
          onWidgetValueChange: this.onWidgetValueChange,
          getDropdownParams: this.getDropdownParams,
          masterTable: this.masterTable,
          handlerOperation: this.handlerOperation,
          checkOperationVisible: this.checkOperationVisible,
          getPrimaryData: this.getPrimaryData,
          formData: this.formData,
          flowData: this.flowInfo,
          formAuth: () => {
            return this.formAuth
          },
          rules: this.rules
        }
      }
    }
  },
  data () {
    return {
      isStart: false,
      taskReadOnly: true,
      // 保存草稿后流程taskId
      draftTaskId: undefined,
      // 保存草稿后流程实例ID
      draftProcessInstanceId: undefined
    }
  },
  methods: {
    onCloseSubForm (refresh, data) {
      if (refresh && this.operationCallback) {
        this.operationCallback(data);
      }
      this.showSubPage = false;
      if (refresh) this.onRefresh();
    },
    getTableData (widget) {
      return widget.relation ? this.formData[widget.relation.variableName] : [];
    },
    setTableData (widget, dataList) {
      if (widget == null) return;
      if (widget.relation) {
        this.formData[widget.relation.variableName] = dataList;
      }
    },
    initFormData () {
      if (this.flowInfo == null || this.flowInfo.processInstanceId == null) return Promise.resolve();
      return new Promise((resolve, reject) => {
        let params = {
          processInstanceId: this.flowInfo.processInstanceId,
          taskId: this.flowInfo.taskId
        }
        // 判断是展示历史流程的数据还是待办流程的数据
        let httpCall = null;
        if (this.isDraft) {
          // 草稿数据
          httpCall = FlowOperationController.viewOnlineDraftData(this, {
            processDefinitionKey: this.flowInfo.processDefinitionKey,
            processInstanceId: this.flowInfo.processInstanceId
          });
        } else if (this.flowInfo.messageId != null) {
          // 抄送消息
          httpCall = FlowOperationController.viewOnlineCopyBusinessData(this, {
            messageId: this.flowInfo.messageId
          });
        } else {
          // 脱敏设置，审批暂时不支持脱敏
          // params.ignoreMaskFields = this.getIgnoreMaskFields();
          httpCall = (this.flowInfo.taskId != null && this.isRuntime) ? FlowOperationController.viewUserTask(this, params) : FlowOperationController.viewHistoricProcessInstance(this, params);
        }
        httpCall.then(res => {
          this.isStart = (res.data == null);
          // 流程数据
          let masterData = (res.data || {})[this.masterTable.datasource.variableName] || {};
          // 初始化表单字段
          let relationNameList = new Map();
          let datasourceName;
          this.form.tableMap.forEach(table => {
            if (table.relation) {
              if (table.relation.relationType === this.SysOnlineRelationType.ONE_TO_ONE || this.isDraft) {
                relationNameList.set(table.relation.variableName, table.relation);
              } else {
                relationNameList.set(table.relation.variableName + 'List', table.relation);
              }
              if (table.relation.relationType === this.SysOnlineRelationType.ONE_TO_ONE) {
                this.formData[table.relation.variableName] = table.columnList.reduce((retObj, column) => {
                  retObj[column.columnName] = undefined;
                  return retObj;
                }, {});
              } else {
                this.formData[table.relation.variableName] = [];
              }
            } else if (table.relation == null) {
              datasourceName = table.datasource.variableName;
            }
          });
          Object.keys(masterData).forEach(async key => {
            let relation = relationNameList.get(key);
            let relationVariableName = (relation || {}).variableName;
            if (relationVariableName == null) {
              // 主表字段
              this.formData[datasourceName][key] = masterData[key];
            } else {
              // 从表字段
              if (relation.relationType === this.SysOnlineRelationType.ONE_TO_MANY && masterData[key]) {
                // 如果是一对多关联字段，判断表单上使用这个字段的table组件是否支持数据加载数据后脚本
                if (Array.isArray(this.tableWidgetList)) {
                  this.tableWidgetList.forEach(async tableWidget => {
                    if (tableWidget.relation && tableWidget.relation.relationId === relation.relationId) {
                      if (typeof tableWidget.eventInfo[this.OnlineFormEventType.AFTER_LOAD_TABLE_DATA] === 'function') {
                        masterData[key] = await tableWidget.eventInfo[this.OnlineFormEventType.AFTER_LOAD_TABLE_DATA](masterData[key]);
                      }
                    }
                  });
                }
              }
              if (masterData[key]) {
                if (!Array.isArray(masterData[key])) {
                  this.formData[relationVariableName] = {
                    ...this.formData[relationVariableName],
                    ...masterData[key]
                  };
                } else {
                  this.formData[relationVariableName] = masterData[key];
                }
              }
            }
          });
          relationNameList = null;
          resolve();
        }).catch(e => {
          reject(e);
        });
      });
    },
    async getFormDataImpl (variableList) {
      let tempObj = {};
      // 获取表单数据
      this.form.tableMap.forEach(table => {
        if (table.relation) {
          if (tempObj.slaveData == null) tempObj.slaveData = {};
          tempObj.slaveData[table.relation.variableName] = this.formData[table.relation.variableName];
        } else if (table.relation == null) {
          tempObj.masterData = this.formData[table.datasource.variableName];
        }
      });
      // 获取流程变量
      if (Array.isArray(variableList)) {
        variableList.forEach(variable => {
          if (!variable.builtin) {
            let column = this.form.columnMap.get(variable.bindColumnId);
            let relation = this.form.relationMap.get(variable.bindRelationId);
            if (column != null) {
              if (tempObj.taskVariableData == null) tempObj.taskVariableData = {};
              if (relation == null) {
                tempObj.taskVariableData[variable.variableName] = this.formData[this.masterTable.datasource.variableName][column.columnName] || '';
              } else {
                tempObj.taskVariableData[variable.variableName] = this.formData[relation.variableName][column.columnName] || '';
              }
            }
          }
        });
      }

      // 执行提交数据前脚本
      if (typeof this.form.eventInfo[this.OnlineFormEventType.BEFORE_COMMIT_FORM_DATA] === 'function') {
        tempObj = await this.form.eventInfo[this.OnlineFormEventType.BEFORE_COMMIT_FORM_DATA](tempObj);
      }
      if (tempObj == null) throw new Error('提交数据前脚本返回数据为空');
      // 把slaveData里的relationVariableName替换成relationId
      if (tempObj.slaveData) {
        let slaveDataKeyList = Object.keys(tempObj.slaveData);
        if (slaveDataKeyList.length > 0) {
          let relationVariableNameMap = new Map();
          this.form.tableMap.forEach(table => {
            if (table.relation != null) {
              relationVariableNameMap.set(table.relation.variableName, table.relation.relationId);
            }
          });
          slaveDataKeyList.forEach(key => {
            let relationId = relationVariableNameMap.get(key);
            if (relationId != null) {
              tempObj.slaveData[relationId] = tempObj.slaveData[key];
            }
            tempObj.slaveData[key] = undefined;
          });
        }
      }

      return tempObj;
    },
    async getFormData (isDraft, variableList) {
      // 获取富文本内容
      if (Array.isArray(this.richEditWidgetList)) {
        this.richEditWidgetList.forEach(richWidget => {
          if (richWidget && richWidget.widgetImpl) {
            this.onValueChange(richWidget, richWidget.widgetImpl.getHtml());
          }
        });
      }
      if (isDraft) {
        let formData = await this.getFormDataImpl(variableList);
        return formData;
      } else {
        await this.$refs.form.validate();
        let formData = await this.getFormDataImpl(variableList);
        return formData;
      }
    },
    viewTaskFormKey () {
      if (
        this.flowInfo == null ||
        this.flowInfo.processDefinitionKey == null ||
        this.flowInfo.processDefinitionKey === ''
      ) {
        return Promise.resolve();
      }
      let paraams = {
        processDefinitionKey: this.flowInfo.processDefinitionKey,
        processInstanceId: this.flowInfo.processInstanceId,
        taskId: this.flowInfo.taskId
      };
      return new Promise((resolve, reject) => {
        FlowOperationController.viewTaskFormKey(this, paraams)
          .then(res => {
            try {
              let temp = JSON.parse(res.data);
              this.taskReadOnly = temp.readOnly == null ? true : temp.readOnly;
              this.formAuth = temp.formAuth;
              Object.keys(this.formAuth || {}).forEach(key => {
                let formAuthItem = this.formAuth[key];
                Object.keys(formAuthItem).forEach(subKey => {
                  let authItem = formAuthItem[subKey];
                  if (authItem && authItem != null && authItem !== '') {
                    formAuthItem[subKey] = authItem.split(',').map(item => parseInt(item));
                  } else {
                    formAuthItem[subKey] = [0, 0];
                  }
                  let disabled = formAuthItem[subKey][0] === 1;
                  let hide = formAuthItem[subKey][1] === 1;
                  formAuthItem[subKey].disabled = disabled;
                  formAuthItem[subKey].hide = hide;
                });
              });
            } catch (e) {
              console.log(e);
              this.formAuth = null;
            }
            resolve();
          })
          .catch(e => {
            reject(e);
          });
      });
    }
  },
  computed: {
    form () {
      let temp = this.buildFormConfig(this.formConfig);
      return temp;
    },
    isDraft () {
      return this.flowInfo ? (this.flowInfo.isDraft === true || this.flowInfo.isDraft === 'true') : false
    },
    rootWidget () {
      return {
        childWidgetList: this.form.widgetList
      }
    },
    isRuntime () {
      return this.flowInfo ? (this.flowInfo.isRuntime === true || this.flowInfo.isRuntime === 'true') : false
    }
  },
  created () {
    this.isReady = false;
    this.viewTaskFormKey().then(() => {
      this.initPage();
      this.initFormWidgetList();
      if (typeof this.form.eventInfo[this.OnlineFormEventType.AFTER_CREATE_FORM] === 'function') {
        this.form.eventInfo[this.OnlineFormEventType.AFTER_CREATE_FORM]();
      }
      this.initWidgetRule();
      this.initFormData().then(() => {
        if (typeof this.form.eventInfo[this.OnlineFormEventType.AFTER_LOAD_FORM_DATA] === 'function') {
          this.form.eventInfo[this.OnlineFormEventType.AFTER_LOAD_FORM_DATA]();
        }
        this.initWidgetLinkage();
      }).catch(e => {
        console.log(e);
      });
      this.isReady = true;
    }).catch(e => {
      console.log(e);
      this.isReady = true;
    });
  }
}
</script>

<style>

</style>
